package com.lhd_gm.scheduledtasksystem.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lhd_gm.scheduledtasksystem.listener.JobLogListener;
import com.lhd_gm.scheduledtasksystem.message.NormalMessage;
import com.lhd_gm.scheduledtasksystem.pojo.*;
import com.lhd_gm.scheduledtasksystem.service.*;
import com.lhd_gm.scheduledtasksystem.utils.DynamicBeanRegistrar;
import com.lhd_gm.scheduledtasksystem.utils.DynamicCodeCompiler;
import com.lhd_gm.scheduledtasksystem.utils.ShellScriptGenerator;
import com.lhd_gm.scheduledtasksystem.utils.TimeUtils;
import com.lhd_gm.scheduledtasksystem.vo.CreateHttpJobVo;
import com.lhd_gm.scheduledtasksystem.vo.CreateJobVo;
import com.lhd_gm.scheduledtasksystem.vo.CreateShellJobVo;
import com.lhd_gm.scheduledtasksystem.vo.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.UUID;

@RestController
@RequestMapping("/quartz")
public class QuartzController {
    private static final String jobaddress ="com.lhd_gm.scheduledtasksystem.job.";
    private static final Logger logger = LoggerFactory.getLogger(JobLogListener.class);
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private QuartzService quartzService;

    @Autowired
    private JobMethodService jobMethodService;

    @Autowired
    private JobHttpService jobHttpService;

    @Autowired
    private JobShellService jobShellService;

    // 创建普通定时任务
    @PostMapping("/createJob")
    public Result createJob(@RequestBody CreateJobVo createJobVo) {
        JobInfo jobInfo = createJobVo.getJobInfo();
        JobMethod jobMethod = createJobVo.getJobMethod();
        // 完善生成类信息
        UUID uuid = UUID.randomUUID();
        String jobId = uuid.toString().replaceAll("-", "");
        jobMethod.setJobId(jobId);
        String className = jobMethod.getJobName();
        jobMethod.setJobName(className+jobId);
        jobMethod.setCode(jobMethod.getCode().replace(className, className+jobId));
        jobMethod.setCreateTime(LocalDateTime.now());
        jobMethod.setUpdateTime(LocalDateTime.now());
        try {
            // 1. 动态编译代码
            Class<?> jobClass = DynamicCodeCompiler.compile(jobMethod.getJobName(), jobMethod.getCode());
            // 2. 注册为Spring Bean（Bean名称与类名一致）
            DynamicBeanRegistrar.registerJobBean(applicationContext, jobMethod.getJobName(), jobClass);
            // 保存生成类信息
            jobMethodService.JobMethodSave(jobMethod);
            // 添加定时任务
            String result = quartzService.addCronJob(jobInfo,jobaddress + jobMethod.getJobName());
            if ("success".equals(result)){
                return Result.success(NormalMessage.ADD_NORMAL_JOB_SUCCESS,jobMethod);
            }else if ("exist".equals(result)){
                return Result.info(NormalMessage.EXIST_JOB);
            }else {
                return Result.error(NormalMessage.ADD_NORMAL_JOB_ERROR);
            }
        } catch (Exception e) {
            // 打印报错信息
            logger.error(e.getMessage());
            return Result.error(NormalMessage.ADD_NORMAL_JOB_ERROR);
        }
    }

//    @PostMapping("/createJob")
//    public String createJob(@RequestBody JobInfo jobInfo) {
//        try {
//            // 添加定时任务
//            return quartzService.addCronJob(jobInfo.getJobName(), jobInfo.getCron(),"com.lhd_gm.jobtest.job.TaskJob");
//        } catch (Exception e) {
//            // 打印报错信息
//            logger.error(e.getMessage());
//            return "定时任务创建失败！";
//        }
//    }

    // 创建Http定时任务
    @PostMapping("/createHttpJob")
    public Result createHttpJob(@RequestBody CreateHttpJobVo createHttpJobVo){
        JobInfo jobInfo = createHttpJobVo.getJobInfo();
        ScheduledHttpTask scheduledHttpTask = createHttpJobVo.getScheduledHttpTask();
        // 完善Http类信息
        JobHttp jobHttp = new JobHttp();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            jobHttp.setHttpUrl(scheduledHttpTask.getHttpUrl());
            jobHttp.setHttpParams(scheduledHttpTask.getHttpParams());
            jobHttp.setHttpMethod(scheduledHttpTask.getHttpMethod());
            jobHttp.setHttpBody(scheduledHttpTask.getHttpBody());
            String headers = objectMapper.writeValueAsString(scheduledHttpTask.getHttpHeaders());
            jobHttp.setHttpHeaders(headers);
            jobHttp.setCreateTime(LocalDateTime.now());
            jobHttp.setUpdateTime(LocalDateTime.now());
            // 保存Http信息
            jobHttpService.JobHttpSave(jobHttp);
            // 添加定时任务
            String shtJson = objectMapper.writeValueAsString(scheduledHttpTask);
            String result = quartzService.addHttpCronJob(jobInfo,jobaddress + "HttpRequestJob",shtJson);
            if ("success".equals(result)){
                return Result.success(NormalMessage.ADD_HTTP_JOB_SUCCESS,jobHttp);
            }else if ("exist".equals(result)){
                return Result.info(NormalMessage.EXIST_JOB);
            }else {
                return Result.error(NormalMessage.ADD_HTTP_JOB_ERROR);
            }
        } catch (Exception e) {
            // 打印报错信息
            logger.error(e.getMessage());
            return Result.error(NormalMessage.ADD_HTTP_JOB_ERROR);
        }
    }

    // 创建Shell脚本定时任务
    @PostMapping("/createShellJob")
    public Result createShellJob(@RequestBody CreateShellJobVo createShellJobVo){
        JobInfo jobInfo = createShellJobVo.getJobInfo();
        ShellTask shellTask = createShellJobVo.getShellTask();
        try {
            String shellName = shellTask.getFileName() +"_"+ TimeUtils.getCurrentTimestamp() + ".sh";
            // 生成脚本
            String shellScriptPath = ShellScriptGenerator.generateScript(shellName, shellTask.getShell());
            // 完善shell类信息
            JobShell jobShell = new JobShell();
            ObjectMapper objectMapper = new ObjectMapper();
            jobShell.setFileName(shellName);
            jobShell.setShell(shellTask.getShell());
            jobShell.setJobType(shellTask.getJobType());
            jobShell.setDescription(shellTask.getDescription());
            jobShell.setScriptPath(shellScriptPath);
            String scriptArgs = objectMapper.writeValueAsString(shellTask.getScriptArgs());
            jobShell.setScriptArgs(scriptArgs);
            String envVars = objectMapper.writeValueAsString(shellTask.getEnvVars());
            jobShell.setEnvVars(envVars);
            jobShell.setTimeout(shellTask.getTimeout());
            jobShell.setCreateTime(LocalDateTime.now());
            jobShell.setUpdateTime(LocalDateTime.now());
            // 保存shell信息
            jobShellService.JobShellSave(jobShell);
            // 添加定时任务
            String stJson = objectMapper.writeValueAsString(shellTask);
            String result = quartzService.addShellCronJob(jobInfo,jobaddress + "ShellJob",stJson, shellScriptPath);
            if ("success".equals(result)){
                return Result.success(NormalMessage.ADD_SHELL_JOB_SUCCESS,jobShell);
            } else if ("exist".equals(result)){
                return Result.info(NormalMessage.EXIST_JOB);
            } else{
                return Result.error(NormalMessage.ADD_SHELL_JOB_ERROR);
            }
        } catch (Exception e) {
            // 打印报错信息
            logger.error(e.getMessage());
            return Result.error(NormalMessage.ADD_SHELL_JOB_ERROR);
        }
    }
    // 修改定时任务
    @PutMapping("/editJob")
    public Result editJob(@RequestBody JobInfo jobInfo) {
        String result =  quartzService.modifyJob(jobInfo);
        if ("success".equals(result)){
            return Result.success(NormalMessage.EDIT_JOB_SUCCESS);
        } else if ("inexistence".equals(result)){
            return Result.info(NormalMessage.INEXISTENCE_JOB);
        } else {
            return Result.error(NormalMessage.EDIT_JOB_ERROR);
        }
    }

    // 删除定时任务
    @DeleteMapping("/deleteJob")
    public Result deleteJob(@RequestBody JobInfo jobInfo) {
        String result = quartzService.deleteCronJob(jobInfo);
        if ("success".equals(result)){
            return Result.success(NormalMessage.DEL_JOB_SUCCESS);
        } else if ("removed".equals(result)){
            return Result.error(NormalMessage.REMOVE_JOB);
        } else {
            return Result.error(NormalMessage.DEL_JOB_ERROR);
        }
    }

    // 执行一次
    @PostMapping("/executeImmediately")
    public Result executeImmediately(@RequestBody CreateJobVo createJobVo) {
        JobInfo jobInfo = createJobVo.getJobInfo();
        JobMethod jobMethod = createJobVo.getJobMethod();
        String result = quartzService.executeImmediately(jobInfo,jobaddress + jobMethod.getJobName());
        if ("success".equals(result)){
            return Result.success(NormalMessage.EXECUTE_JOB_SUCCESS);
        } else {
            return Result.error(NormalMessage.EXECUTE_JOB_ERROR);
        }
    }

    // 暂停任务
    @PutMapping("/pauseJob/{jobName}/{jobGroup}")
    @ResponseBody
    public Result pauseJob(@PathVariable String jobName, @PathVariable String jobGroup) {
        int result = quartzService.pauseJob(jobName, jobGroup);
        if (result > 0){
            return Result.success(NormalMessage.PAUSE_JOB_SUCCESS);
        }else {
            return Result.success(NormalMessage.PAUSE_JOB_ERROR);
        }
    }

    // 恢复任务
    @PutMapping("/resumeJob/{jobName}/{jobGroup}")
    @ResponseBody
    public Result resumeJob(@PathVariable String jobName, @PathVariable String jobGroup) {
        int result = quartzService.resumeJob(jobName, jobGroup);
        if (result > 0){
            return Result.success(NormalMessage.RESUME_JOB_SUCCESS);
        }else {
            return Result.success(NormalMessage.RESUME_JOB_ERROR);
        }
    }

}
